
#include "BSP_USB.h"
#include "BSP.h"
#include "usbd_std.h"
#include "custom_hid_core.h"
#include "KeyBoardMap.h"

usbd_core_handle_struct  usb_device_dev =
{
    .dev_desc = (uint8_t *)&device_descripter,
    .config_desc = (uint8_t *)&configuration_descriptor,
    .strings = usbd_strings,
    .class_init = custom_hid_init,
    .class_deinit = custom_hid_deinit,
    .class_req_handler = custom_hid_req_handler,
    .class_data_handler = custom_hid_data_handler
};

static void USB_Delay(uint32_t t){
	volatile uint32_t c;

	for(c = 0; c < t; c++){
		
	}
}

void USB_HID_Init(void){
	BSP_USB_Connect(0);
	usbd_core_deinit();
	USB_Delay(100000);
	usbd_core_init(&usb_device_dev);
	BSP_USB_Connect(1);
    usb_device_dev.status = USBD_CONNECTED;
}

void USB_HID_Deinit(void){
	BSP_USB_Connect(0);
	usbd_core_deinit();
	BSP_USB_Deinit();
}

int USB_HID_Ready(void){
	return USBD_CONFIGURED == usb_device_dev.status;
}

int USB_IsPlugged(void){
	return USBD_CONNECTED != usb_device_dev.status;
}

extern uint8_t usb_hid_tx_compelet;

static uint8_t hidSendCount;
static uint8_t hidSendBuf[64];

int HID_SendByte(uint8_t byte){
	int ret = 0;
	hidSendBuf[hidSendCount++] = byte;
	if(hidSendCount == 64){
		ret = custom_hid_report_send(&usb_device_dev, hidSendBuf, hidSendCount);
		hidSendCount = 0;
	}
	return ret;
}

void HID_Flush(void){
	if(hidSendCount > 0){
		uint32_t c;
		for(c = hidSendCount; c < 64; c++){
			hidSendBuf[c] = 0;
		}
		custom_hid_report_send(&usb_device_dev, hidSendBuf, c);
		hidSendCount = 0;
	}
}


static int HID_KB_ReportKeyEvent(uint8_t keyEvent, uint8_t shift){
	static uint8_t report[8] = {0};

	if(usb_device_dev.status != USBD_CONFIGURED){
		return -1;
	}
	
	//memset(report, 0, sizeof(report));
	report[0] = shift ? 0x02 : 0x00;
	report[2] = keyEvent;
	
	return key_hid_report_send(&usb_device_dev, report, sizeof(report));
}

static int HID_KB_ReportKey(uint8_t key, uint8_t shift){
	int ret;
	ret = HID_KB_ReportKeyEvent(key, shift); //key down
	if(ret){
		return ret;
	}
	BSP_Sleep_Ms(2);
	ret = HID_KB_ReportKeyEvent(0, 0); //key up
	BSP_Sleep_Ms(2);
	return ret;
}

void HID_KB_Enter(void){
	HID_KB_ReportKey(0x28, 0);
}

void HID_KB_SendKey(uint8_t key){
	int shift = 0;
	int code = KeyMap_ValueToCode(key, &shift);
	if(code < 0){
		return;
	}
	HID_KB_ReportKey(code, shift);
}



